import Cocoa
import AVFoundation

class ViewController: NSViewController {

    private var playerLayer: AVPlayerLayer?
    private var currentWallpaperURL: URL?
    private let wallpaperManager = WallpaperManager.shared
    
    // 新增：图片显示模式
    enum ImageDisplayMode {
        case scaleToFill      // 拉伸填满，不保持比例
        case aspectFit        // 等比缩放，显示全部（可能留空白）
        case aspectFill       // 等比填充，可能裁剪
        case center           // 居中不缩放
    }
    
    private var currentDisplayMode: ImageDisplayMode = .aspectFill
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.wantsLayer = true
        let currentMode = wallpaperManager.getLastDisplayMode() ?? "aspectFill"
        switch currentMode {
        case "fill":
            currentDisplayMode = .scaleToFill
        case "fit":
            currentDisplayMode = .aspectFit
        case "center":
            currentDisplayMode = .center
        default:
            break
        }
        setupObservers()
    }

    override func viewDidAppear() {
        super.viewDidAppear()
        setupWindow()
    }

    private func setupObservers() {
        NotificationCenter.default.addObserver(self, selector: #selector(handleSetWallpaper(_:)), name: .setWallpaper, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(handleClearWallpaper), name: .clearWallpaper, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(handleChangeMode(_:)), name: .init("changeImageDisplayMode"), object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(handleTogglePlayback), name: .togglePlayback, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(handleToggleMute), name: .toggleMute, object: nil)
        
        // 监听 Space 切换
        NSWorkspace.shared.notificationCenter.addObserver(
            self,
            selector: #selector(handleSpaceChanged),
            name: NSWorkspace.activeSpaceDidChangeNotification,
            object: nil
        )
    }

    private func setupWindow() {
        guard let window = view.window else { return }
        window.styleMask = [.borderless]
        window.setFrame(NSScreen.main!.frame, display: true)
        window.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.desktopIconWindow)))
        window.isOpaque = false
        window.backgroundColor = .clear
        window.collectionBehavior = [.canJoinAllSpaces,.stationary,.ignoresCycle]
        window.ignoresMouseEvents = true
    }

    @objc private func handleSetWallpaper(_ notification: Notification) {
        guard let url = notification.userInfo?["url"] as? URL, url != currentWallpaperURL else {
            return
        }
        
        let isVideo = ["mov", "mp4"].contains(url.pathExtension.lowercased())
        
        clearContent()
        currentWallpaperURL = url
        
        if isVideo {
            setSystemWallpaperToFirstFrame(of: url)
            setupPlayer(with: url)
        } else {
            setupImage(with: url, mode: currentDisplayMode)
        }
    }
    
    @objc private func handleClearWallpaper() {
        clearContent()
    }
    
    @objc private func handleChangeMode(_ notification: Notification) {
        guard let mode = notification.userInfo?["mode"] as? String else { return }
        switch mode {
        case "fill":
            setImageDisplayMode(.scaleToFill)
        case "fit":
            setImageDisplayMode(.aspectFit)
        case "aspectFill":
            setImageDisplayMode(.aspectFill)
        case "center":
            setImageDisplayMode(.center)
        default:
            break
        }
    }
    
    @objc private func handleTogglePlayback() {
        guard let player = playerLayer?.player else { return }
        if wallpaperManager.getIsPlaying() {
            player.play()
        } else {
            player.pause()
        }
    }

    @objc private func handleToggleMute() {
        playerLayer?.player?.isMuted = wallpaperManager.getIsMuted()
    }
    
    @objc private func handleSpaceChanged() {
        // 只在当前是视频壁纸时处理
        guard let videoURL = currentWallpaperURL,
              ["mov","mp4"].contains(videoURL.pathExtension.lowercased()) else {
            return
        }
        // 根据当前视频名称拼出保存的 PNG 路径
        let videoName = videoURL.deletingPathExtension().lastPathComponent
        let expectedFirstFramePath = FileManager.default.temporaryDirectory
            .appendingPathComponent("\(videoName).png").path
        // 当前 Space 已经设置的壁纸
        if let screen = NSScreen.main,
           let currentImageURL = NSWorkspace.shared.desktopImageURL(for: screen) {
            if currentImageURL.path == expectedFirstFramePath {
                return
            }
        }
        // 否则，设置视频的第一帧为当前 Space 的壁纸
        setSystemWallpaperToFirstFrame(of: videoURL)
    }

    private func setupImage(with url: URL, mode: ImageDisplayMode) {
        guard let screen = NSScreen.main else { return }
        var options = NSWorkspace.shared.desktopImageOptions(for: screen) ?? [:]

        switch mode {
        case .aspectFill:
            options[.imageScaling] = NSNumber(value: NSImageScaling.scaleProportionallyUpOrDown.rawValue)
            options[.allowClipping] = true     // 允许裁剪，充满屏幕
        case .aspectFit:
            options[.imageScaling] = NSNumber(value: NSImageScaling.scaleProportionallyUpOrDown.rawValue)
            options[.allowClipping] = false    // 不裁剪，留边
        case .scaleToFill:
            options[.imageScaling] = NSNumber(value: NSImageScaling.scaleAxesIndependently.rawValue)
            options[.allowClipping] = true     // 拉伸
        case .center:
            options[.imageScaling] = NSNumber(value: NSImageScaling.scaleNone.rawValue)
            options[.allowClipping] = false    // 居中
        }

        do {
            try NSWorkspace.shared.setDesktopImageURL(url, for: screen, options: options)
        } catch {
            print("设置壁纸失败：\(error)")
        }
    }
    
    private func setSystemWallpaperToFirstFrame(of videoURL: URL) {
        let asset = AVURLAsset(url: videoURL)
        let generator = AVAssetImageGenerator(asset: asset)
        generator.appliesPreferredTrackTransform = true  // 保持方向
        
        generator.generateCGImagesAsynchronously(forTimes: [NSValue(time: .zero)]) { _, cgImage, _, result, error in
            if let cgImage = cgImage, result == .succeeded {
                let image = NSImage(cgImage: cgImage, size: NSSize(width: 160, height: 90))
                do {
                    // 保存成临时文件（png）
                    if let tiffData = image.tiffRepresentation,
                        let bitmap = NSBitmapImageRep(data: tiffData),
                        let pngData = bitmap.representation(using: .png, properties: [:]) {
                        let videoName = videoURL.deletingPathExtension().lastPathComponent
                        let tempDir = FileManager.default.temporaryDirectory
                        let tempFile = tempDir.appendingPathComponent("\(videoName).png")
                        try pngData.write(to: tempFile)
                        // 回到主线程设置系统壁纸
                        DispatchQueue.main.async {
                                self.setupImage(with: tempFile, mode: self.currentDisplayMode)
                        }
                    }
                } catch {
                    print("提取视频第一帧失败: \(error)")
                }
            } else {
                if let error = error {
                    print("Error generating video thumbnail: \(error.localizedDescription)")
                }
            }
        }
    }

    private func setupPlayer(with url: URL) {
        // 先设置系统壁纸为视频的第一帧
        setSystemWallpaperToFirstFrame(of: url)
        
        let player = AVPlayer(url: url)
        player.actionAtItemEnd = .none
        player.isMuted = wallpaperManager.getIsMuted()

        playerLayer = AVPlayerLayer(player: player)
        guard let playerLayer = playerLayer else { return }
        playerLayer.frame = view.bounds
        playerLayer.videoGravity = .resizeAspectFill
        view.layer?.addSublayer(playerLayer)
        
        if wallpaperManager.getIsPlaying() {
            player.play()
        }

        NotificationCenter.default.addObserver(
            self,
            selector: #selector(playerItemDidReachEnd(notification:)),
            name: .AVPlayerItemDidPlayToEndTime,
            object: player.currentItem
        )
    }
    
    private func clearContent() {
        playerLayer?.player?.pause()
        playerLayer?.removeFromSuperlayer()
        playerLayer = nil
        
        currentWallpaperURL = nil
        
        NotificationCenter.default.removeObserver(self, name: .AVPlayerItemDidPlayToEndTime, object: nil)
    }

    @objc private func playerItemDidReachEnd(notification: Notification) {
        if let playerItem = notification.object as? AVPlayerItem {
            playerItem.seek(to: .zero, completionHandler: nil)
        }
    }
    
    // 切换图片显示模式的公开接口**
    func setImageDisplayMode(_ mode: ImageDisplayMode) {
        currentDisplayMode = mode
        // 如果当前是图片壁纸，重新设置图片以应用新模式
        if let url = currentWallpaperURL, !["mov", "mp4"].contains(url.pathExtension.lowercased()) {
            setupImage(with: url, mode: mode)
        }
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}
